package com.deying.httplockserver.core;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import io.netty.bootstrap.ServerBootstrap;  
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;  
import io.netty.channel.ChannelOption;  
import io.netty.channel.EventLoopGroup;  
import io.netty.channel.nio.NioEventLoopGroup;  
import io.netty.channel.socket.SocketChannel;  
import io.netty.channel.socket.nio.NioServerSocketChannel;  
import io.netty.handler.codec.http.HttpRequestDecoder;  
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;  

@Component
public class NettyHttpServer {
	private final Logger logger = LoggerFactory.getLogger(NettyHttpServer.class);
	
	@Resource
	NettyHttpDispatcher nettyHttpDispatcher;
	
	public void start() throws InterruptedException{
		new Thread(new Runnable() {
			@Override
			public void run() {
		        try {
					init();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}  
			}
		}).start();
	}

	//必须要另起线程，不然会阻塞整个程序
	private void init() throws InterruptedException {
		logger.info("启动锁服务");
		EventLoopGroup bossGroup = new NioEventLoopGroup();  
        EventLoopGroup workerGroup = new NioEventLoopGroup();  
        try {  
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .childHandler(
                    		new ChannelInitializer<SocketChannel>() {  
                                @Override  
                                public void initChannel(SocketChannel ch) throws Exception {  
                                    ch.pipeline()
                                    .addLast(new ChannelInboundHandlerAdapter(){
                                    	@Override
                                    	public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
                                    		Attribute<HttpLockRequest> attr = ctx.channel().attr(AttributeKey.<HttpLockRequest>valueOf(HttpLockRequest.class.getSimpleName()));
                                    		HttpLockRequest httpLockRequest = attr.get();
                                    		if(httpLockRequest!=null){
                                    			logger.debug("request {}-{} 客户端tcp断开",httpLockRequest.getName(),httpLockRequest.getTid());
                                    			httpLockRequest.postUnBindWorker();
                                    		}
                                    		attr.set(null);
                                    		ctx.close();
                                    	}
                                    })
                                    .addLast(new HttpResponseEncoder())
                                    .addLast(new HttpRequestDecoder())
                                    .addLast(nettyHttpDispatcher);  
                                }  
                            })
                    .childOption(ChannelOption.SO_REUSEADDR, true)
            		.childOption(ChannelOption.TCP_NODELAY, true);  
  
            ChannelFuture f = b.bind(8000).sync();  
            f.channel().closeFuture().sync();  
        }catch(Exception e){
        	e.printStackTrace();
    		logger.error("启动锁服务异常 {}",e.getMessage());
        } finally {  
            workerGroup.shutdownGracefully();  
            bossGroup.shutdownGracefully();  
        }
	}
	

}
